package com.gitee.wsl.struct.grammar.parser.context

import com.gitee.wsl.struct.grammar.parser.result.ParseErrorContext
import com.gitee.wsl.struct.grammar.parser.result.ParseErrorContextProvider
import com.gitee.wsl.struct.grammar.parser.token.TokenMatch

internal class LastTokenMatchContext(
    val input: String,
    var currentOffset: Int,
    var lastMatch: TokenMatch? = null,
) : ParseErrorContextProvider {

    override fun toString() = "LastTokenMatchContext(currentOffset=$currentOffset, lastMatch=$lastMatch)"

    override fun getParseErrorContext(offset: Int): ParseErrorContext? {
        if (offset != currentOffset) {
            return null
        }

        val lastMatch = this.lastMatch
        val lookAhead = 20
        return if (lastMatch == null || lastMatch.nextOffset != offset) {
            ParseErrorContext(
                inputSection = getInputSection(offset, offset + lookAhead),
                lookBehind = 0,
                lookAhead = lookAhead,
                previousTokenMatch = null
            )
        } else {
            ParseErrorContext(
                inputSection = getInputSection(lastMatch.offset, lastMatch.nextOffset + lookAhead),
                lookBehind = lastMatch.length,
                lookAhead = lookAhead,
                previousTokenMatch = lastMatch
            )
        }
    }

    private fun getInputSection(inputSectionStart: Int, inputSectionStop: Int) =
        input.substring(inputSectionStart, inputSectionStop.coerceAtMost(input.length))
}